import type { PageBlock, RD } from './types';

import { type Reactive, reactive } from 'vue';

import { createRender } from './node';

const states = reactive<Record<string, any>>({});

export function createFunction(code: string, context: Context) {
  return new Function('__scope__', `with(__scope__){ return ${code}}`)(context);
}

export class Context {
  public block: PageBlock;
  public createRender = createRender;

  public state: Reactive<RD> = reactive({});

  constructor(block: PageBlock) {
    this.block = block;
    this.createRender();
    // this.createRender = createRender.bind(this);
  }

  private parseExpression(code: string) {
    return createFunction(code, this);
  }

  private parseFunction(code: string) {
    return createFunction(code, this);
  }

  private parseState() {
    const blockId = this.block.id;
    const state = this.block.state || {};
  }

  // createRender() {
  //   return createRender.call(this);
  // }

  parse(node: any) {
    if (!node) return node;
    if (Array.isArray(node)) {
      return node.map((obj) => {
        return this.parse(obj);
      });
    } else if (typeof node === 'object') {
      if (node?.type) {
        if (node.type === 'JsExpression' || node.type === 'JsModel') {
          return this.parseExpression(node.value);
        } else if (node.type === 'JsFunction') {
          return this.parseFunction(node.value);
        }
      }
      Object.keys(node).forEach((key) => {
        node[key] = this.parse(node[key]);
      });
      return node;
    } else {
      if (node.toString().startsWith('{{') && node.toString().endsWith('}}')) {
        const code = node.value.toString().replace('{{', '').replace('}}', '').trim();
        return this.parseExpression(code);
      }
      return node;
    }
  }
}
